package com.ccteam.fluidmusic.ui.artist

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import com.ccteam.fluidmusic.NavAlbumDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentArtistDetailAlbumPagerBinding
import com.ccteam.fluidmusic.view.adapters.AlbumListItemAdapter
import com.ccteam.fluidmusic.view.adapters.ArtistAlbumListAdapter
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.shared.result.album.AlbumListItem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class ArtistDetailAlbumPagerFragment : Fragment() {

    private var _binding: FragmentArtistDetailAlbumPagerBinding? = null
    private val binding get() = _binding!!

    private val artistDetailAlbumViewModel: ArtistDetailAlbumViewModel by viewModels()
    private val artistDetailViewModel: ArtistDetailViewModel by viewModels(ownerProducer = {parentFragment ?: this})

    companion object {
        @JvmStatic
        fun newInstance(artistId: String): ArtistDetailAlbumPagerFragment {
            return ArtistDetailAlbumPagerFragment().apply {
                arguments = Bundle().apply {
                    putString("artistId", artistId)
                }
            }
        }
    }

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentArtistDetailAlbumPagerBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val adapter = ArtistAlbumListAdapter(callback)

        lightBounceEdgeEffectFactory.applyBounceView(binding.rvArtistDetailAlbum,this)
        binding.rvArtistDetailAlbum.edgeEffectFactory = lightBounceEdgeEffectFactory

        binding.rvArtistDetailAlbum.adapter = adapter.withLoadStateFooter(
            CustomLoadStateAdapter(adapter){
                adapter.retry()
            }
        )
        viewLifecycleOwner.lifecycleScope.launch {
            artistDetailAlbumViewModel.artistAlbumFlow.collectLatest {
                adapter.submitData(it)
            }
        }
        viewLifecycleOwner.lifecycleScope.launch {
            adapter.loadStateFlow.collectLatest { state ->
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)
                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && adapter.itemCount < 1)
            }
        }

        binding.statusView.setRetryClickListener {
            artistDetailViewModel.refreshArtistInfo()
            adapter.refresh()
        }
    }

    private val callback = object: AlbumListItemAdapter.AlbumListItemCallback {

        override fun onClickItem(view: View, albumItem: AlbumListItem) {
            val transitionName = getString(R.string.album_detail_transition_name)
            val extra = FragmentNavigatorExtras(view to transitionName)

            findNavController().navigate(
                NavAlbumDirections.actionGlobalAlbumDetailFragment(
                albumItem.albumId
            ),extra)
        }

    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}